package com.homedo.async.mysql.support.prepare.insert;

import com.blinkfox.zealot.bean.SqlInfo;
import com.blinkfox.zealot.core.ZealotKhala;
import com.google.common.collect.Lists;
import com.homedo.async.mysql.support.meta.EntityMetaData;
import com.homedo.async.mysql.support.prepare.util.CollectRecordColumnValUtil;
import io.vertx.sqlclient.Tuple;
import com.homedo.plainly.logger.Logger;
import com.homedo.plainly.logger.LoggerFactory;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author jgshun
 * @date 2020/3/5 1:56 PM
 */
public abstract class Records2Sql4Insert {
    private static final Logger _LOGGER = LoggerFactory.getLogger(Records2Sql4Insert.class);


    public static <T> Object[] prepare(EntityMetaData<T> entityMetaData, Iterable<T> records, boolean includeNullVals) {
        Object[] prepareSelectSql = new Object[2];

        ZealotKhala sqlKhala = ZealotKhala.start()
                .insertInto(entityMetaData.getTableName());

        boolean isFirstLoop = true;//第一个循环

        Iterator<T> recordIterator = records.iterator();

        List<Tuple> allColumnVals = Lists.newArrayList();

        while (recordIterator.hasNext()) {

            T record = recordIterator.next();

            Map<String, Object> columnNameValMap = CollectRecordColumnValUtil.collect(record, entityMetaData, includeNullVals);

            if (!columnNameValMap.isEmpty()) {

                List<Object> columnVals = columnNameValMap.keySet().stream().map(e -> {
                    return columnNameValMap.get(e);
                }).collect(Collectors.toList());

                allColumnVals.add(Tuple.tuple(columnVals));

                if (isFirstLoop) {
                    sqlKhala.text(" ( ").text(columnNameValMap.keySet().stream().collect(Collectors.joining(", "))).text(" ) ");
                    sqlKhala.values(" ");
                    isFirstLoop = false;

                    sqlKhala.text(" ( ");

                    sqlKhala.text(columnVals.stream().map(e -> " ? ").collect(Collectors.joining(", ")));

                    sqlKhala.text(" ) ");
                }

            } else {
                _LOGGER.error("[列表中包含缺少插入数据的条目：{}]", sqlKhala.end().getSql());
                throw new RuntimeException("[列表中包含缺少插入数据的条目]");
            }
        }

        sqlKhala.param(allColumnVals);

        SqlInfo sqlInfo = sqlKhala.end();

        prepareSelectSql[0] = sqlInfo.getSql();
        prepareSelectSql[1] = sqlInfo.getParams();

        return prepareSelectSql;
    }

}

